﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Quaternion
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using Unity.IL2CPP.CompilerServices;
using UnityEngine.Bindings;
using UnityEngine.Internal;
using UnityEngine.Scripting;

#nullable disable
namespace UnityEngine
{
  /// <summary>
  ///   <para>Quaternions are used to represent rotations.</para>
  /// </summary>
  [NativeType(Header = "Runtime/Math/Quaternion.h")]
  [NativeHeader("Runtime/Math/MathScripting.h")]
  [Il2CppEagerStaticClassConstruction]
  [UsedByNativeCode]
  /// <summary>
  ///   <para>Constructs new Quaternion with given x,y,z,w components.</para>
  /// </summary>
  /// <param name="x"></param>
  /// <param name="y"></param>
  /// <param name="z"></param>
  /// <param name="w"></param>
  [method: MethodImpl((MethodImplOptions) 256)]
  public struct Quaternion(float x, float y, float z, float w) : IEquatable<Quaternion>, IFormattable
  {
    /// <summary>
    ///   <para>X component of the Quaternion. Don't modify this directly unless you know quaternions inside out.</para>
    /// </summary>
    public float x = x;
    /// <summary>
    ///   <para>Y component of the Quaternion. Don't modify this directly unless you know quaternions inside out.</para>
    /// </summary>
    public float y = y;
    /// <summary>
    ///   <para>Z component of the Quaternion. Don't modify this directly unless you know quaternions inside out.</para>
    /// </summary>
    public float z = z;
    /// <summary>
    ///   <para>W component of the Quaternion. Do not directly modify quaternions.</para>
    /// </summary>
    public float w = w;
    private static readonly Quaternion identityQuaternion = new Quaternion(0.0f, 0.0f, 0.0f, 1f);
    public const float kEpsilon = 1E-06f;

    /// <summary>
    ///   <para>Creates a rotation from fromDirection to toDirection.</para>
    /// </summary>
    /// <param name="fromDirection">A non-unit or unit vector representing a direction axis to rotate.</param>
    /// <param name="toDirection">A non-unit or unit vector representing the target direction axis.</param>
    /// <returns>
    ///   <para>A unit quaternion which rotates from fromDirection to toDirection.</para>
    /// </returns>
    [FreeFunction("FromToQuaternionSafe", IsThreadSafe = true)]
    public static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection)
    {
      Quaternion ret;
      Quaternion.FromToRotation_Injected(ref fromDirection, ref toDirection, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Returns the Inverse of rotation.</para>
    /// </summary>
    /// <param name="rotation"></param>
    [FreeFunction(IsThreadSafe = true)]
    public static Quaternion Inverse(Quaternion rotation)
    {
      Quaternion ret;
      Quaternion.Inverse_Injected(ref rotation, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Spherically linear interpolates between unit quaternions a and b by a ratio of t.</para>
    /// </summary>
    /// <param name="a">Start unit quaternion value, returned when t = 0.</param>
    /// <param name="b">End unit quaternion value, returned when t = 1.</param>
    /// <param name="t">Interpolation ratio. Value is clamped to the range [0, 1].</param>
    /// <returns>
    ///   <para>A unit quaternion spherically interpolated between quaternions a and b.</para>
    /// </returns>
    [FreeFunction("QuaternionScripting::Slerp", IsThreadSafe = true)]
    public static Quaternion Slerp(Quaternion a, Quaternion b, float t)
    {
      Quaternion ret;
      Quaternion.Slerp_Injected(ref a, ref b, t, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Spherically linear interpolates between unit quaternions a and b by t.</para>
    /// </summary>
    /// <param name="a">Start unit quaternion value, returned when t = 0.</param>
    /// <param name="b">End unit quaternion value, returned when t = 1.</param>
    /// <param name="t">Interpolation ratio. Value is unclamped.</param>
    /// <returns>
    ///   <para>A unit quaternion spherically interpolated between unit quaternions a and b.</para>
    /// </returns>
    [FreeFunction("QuaternionScripting::SlerpUnclamped", IsThreadSafe = true)]
    public static Quaternion SlerpUnclamped(Quaternion a, Quaternion b, float t)
    {
      Quaternion ret;
      Quaternion.SlerpUnclamped_Injected(ref a, ref b, t, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Interpolates between a and b by t and normalizes the result afterwards.</para>
    /// </summary>
    /// <param name="a">Start unit quaternion value, returned when t = 0.</param>
    /// <param name="b">End unit quaternion value, returned when t = 1.</param>
    /// <param name="t">Interpolation ratio. The value is clamped to the range [0, 1].</param>
    /// <returns>
    ///   <para>A unit quaternion interpolated between quaternions a and b.</para>
    /// </returns>
    [FreeFunction("QuaternionScripting::Lerp", IsThreadSafe = true)]
    public static Quaternion Lerp(Quaternion a, Quaternion b, float t)
    {
      Quaternion ret;
      Quaternion.Lerp_Injected(ref a, ref b, t, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Interpolates between a and b by t and normalizes the result afterwards. The parameter t is not clamped.</para>
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <param name="t"></param>
    [FreeFunction("QuaternionScripting::LerpUnclamped", IsThreadSafe = true)]
    public static Quaternion LerpUnclamped(Quaternion a, Quaternion b, float t)
    {
      Quaternion ret;
      Quaternion.LerpUnclamped_Injected(ref a, ref b, t, out ret);
      return ret;
    }

    [FreeFunction("EulerToQuaternion", IsThreadSafe = true)]
    private static Quaternion Internal_FromEulerRad(Vector3 euler)
    {
      Quaternion ret;
      Quaternion.Internal_FromEulerRad_Injected(ref euler, out ret);
      return ret;
    }

    [FreeFunction("QuaternionScripting::ToEuler", IsThreadSafe = true)]
    private static Vector3 Internal_ToEulerRad(Quaternion rotation)
    {
      Vector3 ret;
      Quaternion.Internal_ToEulerRad_Injected(ref rotation, out ret);
      return ret;
    }

    [FreeFunction("QuaternionScripting::ToAxisAngle", IsThreadSafe = true)]
    private static void Internal_ToAxisAngleRad(Quaternion q, out Vector3 axis, out float angle)
    {
      Quaternion.Internal_ToAxisAngleRad_Injected(ref q, out axis, out angle);
    }

    /// <summary>
    ///   <para>Creates a rotation which rotates angle degrees around axis.</para>
    /// </summary>
    /// <param name="angle"></param>
    /// <param name="axis"></param>
    [FreeFunction("QuaternionScripting::AngleAxis", IsThreadSafe = true)]
    public static Quaternion AngleAxis(float angle, Vector3 axis)
    {
      Quaternion ret;
      Quaternion.AngleAxis_Injected(angle, ref axis, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Creates a rotation with the specified forward and upwards directions.</para>
    /// </summary>
    /// <param name="forward">The direction to look in.</param>
    /// <param name="upwards">The vector that defines in which direction up is.</param>
    [FreeFunction("QuaternionScripting::LookRotation", IsThreadSafe = true)]
    public static Quaternion LookRotation(Vector3 forward, [DefaultValue("Vector3.up")] Vector3 upwards)
    {
      Quaternion ret;
      Quaternion.LookRotation_Injected(ref forward, ref upwards, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Creates a rotation with the specified forward and upwards directions.</para>
    /// </summary>
    /// <param name="forward">The direction to look in.</param>
    /// <param name="upwards">The vector that defines in which direction up is.</param>
    [ExcludeFromDocs]
    public static Quaternion LookRotation(Vector3 forward)
    {
      return Quaternion.LookRotation(forward, Vector3.up);
    }

    public float this[int index]
    {
      [MethodImpl((MethodImplOptions) 256)] get
      {
        switch (index)
        {
          case 0:
            return this.x;
          case 1:
            return this.y;
          case 2:
            return this.z;
          case 3:
            return this.w;
          default:
            throw new IndexOutOfRangeException("Invalid Quaternion index!");
        }
      }
      [MethodImpl((MethodImplOptions) 256)] set
      {
        switch (index)
        {
          case 0:
            this.x = value;
            break;
          case 1:
            this.y = value;
            break;
          case 2:
            this.z = value;
            break;
          case 3:
            this.w = value;
            break;
          default:
            throw new IndexOutOfRangeException("Invalid Quaternion index!");
        }
      }
    }

    /// <summary>
    ///   <para>Set x, y, z and w components of an existing Quaternion.</para>
    /// </summary>
    /// <param name="newX"></param>
    /// <param name="newY"></param>
    /// <param name="newZ"></param>
    /// <param name="newW"></param>
    [MethodImpl((MethodImplOptions) 256)]
    public void Set(float newX, float newY, float newZ, float newW)
    {
      this.x = newX;
      this.y = newY;
      this.z = newZ;
      this.w = newW;
    }

    /// <summary>
    ///   <para>The identity rotation (Read Only).</para>
    /// </summary>
    public static Quaternion identity
    {
      [MethodImpl((MethodImplOptions) 256)] get => Quaternion.identityQuaternion;
    }

    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion operator *(Quaternion lhs, Quaternion rhs)
    {
      return new Quaternion((float) ((double) lhs.w * (double) rhs.x + (double) lhs.x * (double) rhs.w + (double) lhs.y * (double) rhs.z - (double) lhs.z * (double) rhs.y), (float) ((double) lhs.w * (double) rhs.y + (double) lhs.y * (double) rhs.w + (double) lhs.z * (double) rhs.x - (double) lhs.x * (double) rhs.z), (float) ((double) lhs.w * (double) rhs.z + (double) lhs.z * (double) rhs.w + (double) lhs.x * (double) rhs.y - (double) lhs.y * (double) rhs.x), (float) ((double) lhs.w * (double) rhs.w - (double) lhs.x * (double) rhs.x - (double) lhs.y * (double) rhs.y - (double) lhs.z * (double) rhs.z));
    }

    public static Vector3 operator *(Quaternion rotation, Vector3 point)
    {
      float num1 = rotation.x * 2f;
      float num2 = rotation.y * 2f;
      float num3 = rotation.z * 2f;
      float num4 = rotation.x * num1;
      float num5 = rotation.y * num2;
      float num6 = rotation.z * num3;
      float num7 = rotation.x * num2;
      float num8 = rotation.x * num3;
      float num9 = rotation.y * num3;
      float num10 = rotation.w * num1;
      float num11 = rotation.w * num2;
      float num12 = rotation.w * num3;
      Vector3 vector3;
      vector3.x = (float) ((1.0 - ((double) num5 + (double) num6)) * (double) point.x + ((double) num7 - (double) num12) * (double) point.y + ((double) num8 + (double) num11) * (double) point.z);
      vector3.y = (float) (((double) num7 + (double) num12) * (double) point.x + (1.0 - ((double) num4 + (double) num6)) * (double) point.y + ((double) num9 - (double) num10) * (double) point.z);
      vector3.z = (float) (((double) num8 - (double) num11) * (double) point.x + ((double) num9 + (double) num10) * (double) point.y + (1.0 - ((double) num4 + (double) num5)) * (double) point.z);
      return vector3;
    }

    [MethodImpl((MethodImplOptions) 256)]
    private static bool IsEqualUsingDot(float dot) => (double) dot > 0.99999898672103882;

    [MethodImpl((MethodImplOptions) 256)]
    public static bool operator ==(Quaternion lhs, Quaternion rhs)
    {
      return Quaternion.IsEqualUsingDot(Quaternion.Dot(lhs, rhs));
    }

    [MethodImpl((MethodImplOptions) 256)]
    public static bool operator !=(Quaternion lhs, Quaternion rhs) => !(lhs == rhs);

    /// <summary>
    ///   <para>The dot product between two rotations.</para>
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    [MethodImpl((MethodImplOptions) 256)]
    public static float Dot(Quaternion a, Quaternion b)
    {
      return (float) ((double) a.x * (double) b.x + (double) a.y * (double) b.y + (double) a.z * (double) b.z + (double) a.w * (double) b.w);
    }

    /// <summary>
    ///   <para>Creates a rotation with the specified forward and upwards directions.</para>
    /// </summary>
    /// <param name="view">The direction to look in.</param>
    /// <param name="up">The vector that defines in which direction up is.</param>
    [ExcludeFromDocs]
    [MethodImpl((MethodImplOptions) 256)]
    public void SetLookRotation(Vector3 view)
    {
      Vector3 up = Vector3.up;
      this.SetLookRotation(view, up);
    }

    /// <summary>
    ///   <para>Creates a rotation with the specified forward and upwards directions.</para>
    /// </summary>
    /// <param name="view">The direction to look in.</param>
    /// <param name="up">The vector that defines in which direction up is.</param>
    [MethodImpl((MethodImplOptions) 256)]
    public void SetLookRotation(Vector3 view, [DefaultValue("Vector3.up")] Vector3 up)
    {
      this = Quaternion.LookRotation(view, up);
    }

    /// <summary>
    ///   <para>Returns the angle in degrees between two rotations a and b. The resulting angle ranges from 0 to 180.</para>
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    [MethodImpl((MethodImplOptions) 256)]
    public static float Angle(Quaternion a, Quaternion b)
    {
      float num = Mathf.Min(Mathf.Abs(Quaternion.Dot(a, b)), 1f);
      return Quaternion.IsEqualUsingDot(num) ? 0.0f : (float) ((double) Mathf.Acos(num) * 2.0 * 57.295780181884766);
    }

    private static Vector3 Internal_MakePositive(Vector3 euler)
    {
      float num1 = -9f / (500f * Math.PI);
      float num2 = 360f + num1;
      if ((double) euler.x < (double) num1)
        euler.x += 360f;
      else if ((double) euler.x > (double) num2)
        euler.x -= 360f;
      if ((double) euler.y < (double) num1)
        euler.y += 360f;
      else if ((double) euler.y > (double) num2)
        euler.y -= 360f;
      if ((double) euler.z < (double) num1)
        euler.z += 360f;
      else if ((double) euler.z > (double) num2)
        euler.z -= 360f;
      return euler;
    }

    /// <summary>
    ///   <para>Returns or sets the euler angle representation of the rotation in degrees.</para>
    /// </summary>
    public Vector3 eulerAngles
    {
      [MethodImpl((MethodImplOptions) 256)] get
      {
        return Quaternion.Internal_MakePositive(Quaternion.Internal_ToEulerRad(this) * 57.29578f);
      }
      [MethodImpl((MethodImplOptions) 256)] set
      {
        this = Quaternion.Internal_FromEulerRad(value * ((float) Math.PI / 180f));
      }
    }

    /// <summary>
    ///   <para>Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis; applied in that order.</para>
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <param name="z"></param>
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion Euler(float x, float y, float z)
    {
      return Quaternion.Internal_FromEulerRad(new Vector3(x, y, z) * ((float) Math.PI / 180f));
    }

    /// <summary>
    ///   <para>Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis.</para>
    /// </summary>
    /// <param name="euler"></param>
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion Euler(Vector3 euler)
    {
      return Quaternion.Internal_FromEulerRad(euler * ((float) Math.PI / 180f));
    }

    [MethodImpl((MethodImplOptions) 256)]
    public void ToAngleAxis(out float angle, out Vector3 axis)
    {
      Quaternion.Internal_ToAxisAngleRad(this, out axis, out angle);
      angle *= 57.29578f;
    }

    /// <summary>
    ///   <para>Creates a rotation which rotates from fromDirection to toDirection.</para>
    /// </summary>
    /// <param name="fromDirection"></param>
    /// <param name="toDirection"></param>
    [MethodImpl((MethodImplOptions) 256)]
    public void SetFromToRotation(Vector3 fromDirection, Vector3 toDirection)
    {
      this = Quaternion.FromToRotation(fromDirection, toDirection);
    }

    /// <summary>
    ///   <para>Rotates a rotation from towards to.</para>
    /// </summary>
    /// <param name="from">The unit quaternion to be aligned with to.</param>
    /// <param name="to">The target unit quaternion.</param>
    /// <param name="maxDegreesDelta">The maximum angle in degrees allowed for this rotation.</param>
    /// <returns>
    ///   <para>A unit quaternion rotated towards to by an angular step of maxDegreesDelta.</para>
    /// </returns>
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta)
    {
      float num = Quaternion.Angle(from, to);
      return (double) num == 0.0 ? to : Quaternion.SlerpUnclamped(from, to, Mathf.Min(1f, maxDegreesDelta / num));
    }

    /// <summary>
    ///   <para>Converts this quaternion to a quaternion with the same orientation but with a magnitude of 1.0.</para>
    /// </summary>
    /// <param name="q"></param>
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion Normalize(Quaternion q)
    {
      float num = Mathf.Sqrt(Quaternion.Dot(q, q));
      return (double) num < (double) Mathf.Epsilon ? Quaternion.identity : new Quaternion(q.x / num, q.y / num, q.z / num, q.w / num);
    }

    [MethodImpl((MethodImplOptions) 256)]
    public void Normalize() => this = Quaternion.Normalize(this);

    /// <summary>
    ///   <para>Returns this quaternion with a magnitude of 1 (Read Only).</para>
    /// </summary>
    public Quaternion normalized
    {
      [MethodImpl((MethodImplOptions) 256)] get => Quaternion.Normalize(this);
    }

    [MethodImpl((MethodImplOptions) 256)]
    public override int GetHashCode()
    {
      return this.x.GetHashCode() ^ this.y.GetHashCode() << 2 ^ this.z.GetHashCode() >> 2 ^ this.w.GetHashCode() >> 1;
    }

    [MethodImpl((MethodImplOptions) 256)]
    public override bool Equals(object other) => other is Quaternion other1 && this.Equals(other1);

    [MethodImpl((MethodImplOptions) 256)]
    public bool Equals(Quaternion other)
    {
      return this.x.Equals(other.x) && this.y.Equals(other.y) && this.z.Equals(other.z) && this.w.Equals(other.w);
    }

    /// <summary>
    ///   <para>Returns a formatted string for this quaternion.</para>
    /// </summary>
    /// <param name="format">A numeric format string.</param>
    /// <param name="formatProvider">An object that specifies culture-specific formatting.</param>
    public override string ToString() => this.ToString((string) null, (IFormatProvider) null);

    /// <summary>
    ///   <para>Returns a formatted string for this quaternion.</para>
    /// </summary>
    /// <param name="format">A numeric format string.</param>
    /// <param name="formatProvider">An object that specifies culture-specific formatting.</param>
    public string ToString(string format) => this.ToString(format, (IFormatProvider) null);

    /// <summary>
    ///   <para>Returns a formatted string for this quaternion.</para>
    /// </summary>
    /// <param name="format">A numeric format string.</param>
    /// <param name="formatProvider">An object that specifies culture-specific formatting.</param>
    public string ToString(string format, IFormatProvider formatProvider)
    {
      if (string.IsNullOrEmpty(format))
        format = "F5";
      if (formatProvider == null)
        formatProvider = (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat;
      return UnityString.Format("({0}, {1}, {2}, {3})", (object) this.x.ToString(format, formatProvider), (object) this.y.ToString(format, formatProvider), (object) this.z.ToString(format, formatProvider), (object) this.w.ToString(format, formatProvider));
    }

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion EulerRotation(float x, float y, float z)
    {
      return Quaternion.Internal_FromEulerRad(new Vector3(x, y, z));
    }

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion EulerRotation(Vector3 euler)
    {
      return Quaternion.Internal_FromEulerRad(euler);
    }

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public void SetEulerRotation(float x, float y, float z)
    {
      this = Quaternion.Internal_FromEulerRad(new Vector3(x, y, z));
    }

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public void SetEulerRotation(Vector3 euler) => this = Quaternion.Internal_FromEulerRad(euler);

    [Obsolete("Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public Vector3 ToEuler() => Quaternion.Internal_ToEulerRad(this);

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion EulerAngles(float x, float y, float z)
    {
      return Quaternion.Internal_FromEulerRad(new Vector3(x, y, z));
    }

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion EulerAngles(Vector3 euler) => Quaternion.Internal_FromEulerRad(euler);

    [Obsolete("Use Quaternion.ToAngleAxis instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public void ToAxisAngle(out Vector3 axis, out float angle)
    {
      Quaternion.Internal_ToAxisAngleRad(this, out axis, out angle);
    }

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public void SetEulerAngles(float x, float y, float z)
    {
      this.SetEulerRotation(new Vector3(x, y, z));
    }

    [Obsolete("Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public void SetEulerAngles(Vector3 euler) => this = Quaternion.EulerRotation(euler);

    [Obsolete("Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public static Vector3 ToEulerAngles(Quaternion rotation)
    {
      return Quaternion.Internal_ToEulerRad(rotation);
    }

    [Obsolete("Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public Vector3 ToEulerAngles() => Quaternion.Internal_ToEulerRad(this);

    [Obsolete("Use Quaternion.AngleAxis instead. This function was deprecated because it uses radians instead of degrees.")]
    [MethodImpl((MethodImplOptions) 256)]
    public void SetAxisAngle(Vector3 axis, float angle) => this = Quaternion.AxisAngle(axis, angle);

    [Obsolete("Use Quaternion.AngleAxis instead. This function was deprecated because it uses radians instead of degrees")]
    [MethodImpl((MethodImplOptions) 256)]
    public static Quaternion AxisAngle(Vector3 axis, float angle)
    {
      return Quaternion.AngleAxis(57.29578f * angle, axis);
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void FromToRotation_Injected(
      ref Vector3 fromDirection,
      ref Vector3 toDirection,
      out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Inverse_Injected(ref Quaternion rotation, out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Slerp_Injected(
      ref Quaternion a,
      ref Quaternion b,
      float t,
      out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void SlerpUnclamped_Injected(
      ref Quaternion a,
      ref Quaternion b,
      float t,
      out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Lerp_Injected(
      ref Quaternion a,
      ref Quaternion b,
      float t,
      out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void LerpUnclamped_Injected(
      ref Quaternion a,
      ref Quaternion b,
      float t,
      out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Internal_FromEulerRad_Injected(ref Vector3 euler, out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Internal_ToEulerRad_Injected(
      ref Quaternion rotation,
      out Vector3 ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Internal_ToAxisAngleRad_Injected(
      ref Quaternion q,
      out Vector3 axis,
      out float angle);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void AngleAxis_Injected(
      float angle,
      ref Vector3 axis,
      out Quaternion ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void LookRotation_Injected(
      ref Vector3 forward,
      [DefaultValue("Vector3.up")] ref Vector3 upwards,
      out Quaternion ret);
  }
}
